package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.module.common.utility.Constant;
import com.motu.monstercity.protocol.Common;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemRedPointResponse;
import com.motu.monstercity.protocol.CsGameSystem.RedPoint_Secretary;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.partner.PartnerConstant;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.commondata.secretary.SecretaryIdentity;
import com.motu.monstercity.server.game.commondata.secretary.SecretaryMain;
import com.motu.monstercity.server.game.commondata.secretary.SecretaryPotentialSkill;
import com.motu.monstercity.server.game.commondata.skill.Skill;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.log.MotuLogManager;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class SecretaryManager extends SecretaryUserData {
    private static Logger logger = LoggerFactory.getLogger(SecretaryManager.class);

    // 秘书数据重算干员战力时需要用到
    public static void loadInitSecretaryData(Common.PBUserData.Builder pbUserData, UserInfo userInfo, List<UserSecretary> secretaryList)
    {
        long userId = userInfo.getId();
        int totalCharm = 0;// 总的魅力值
        for (UserSecretary userSecretary : getUserSecretaries(userId)) {
            secretaryList.add(userSecretary);
            ProtoDataUtils.updatePBUserData(pbUserData, userSecretary, true);
            totalCharm+= userSecretary.getCharm();
        }
        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_200, totalCharm);// 更新主线任务,成就,日常任务的进度
        List<UserSecretaryFragment> fragmentList = getUserSecretaryFragments(userId);
        for (UserSecretaryFragment userSecretaryFragment : fragmentList) {
            ProtoDataUtils.updatePBUserData(pbUserData, userSecretaryFragment, true);
        }
    }

    public static void addRewardSecretary(UserInfo userInfo, int secretaryId, Common.PBUserData.Builder pbUserData, Object... logParams) {
        SecretaryMain secretaryMain = getSecretaryMain(secretaryId);
        if (secretaryMain == null) {
            logger.error("SecretaryMain not found for id {}", secretaryId);
            return;
        }
        UserSecretary userSecretary = getUserSecretary(userInfo.getId(), secretaryId);
        if (userSecretary != null) {
            logger.info("User {} has already got secretary {}", userInfo.getId(), secretaryId);
            return;
        }
        UserPower userPower = GameUser.getUserPower(userInfo.getId());
        UserAffair userAffair = GameUser.getUserAffair(userInfo.getId());
        addUserSecretary(userInfo, userPower, userAffair, secretaryMain, secretaryId, pbUserData, logParams);
    }

    // 添加秘书 会增加羁绊干员的战力，解锁经营技能会增加某性格建筑的城市收益
    public static UserSecretary addUserSecretary(UserInfo userInfo, UserPower userPower, UserAffair userAffair, SecretaryMain secretaryMain, int secretaryId, Common.PBUserData.Builder pbUserData, Object... logParams) {
        long userId = userInfo.getId();
        UserSecretary userSecretary = new UserSecretary(pbUserData, userInfo, userPower, secretaryMain);

        // 羁绊技能增加的战力
        long addPower = 0L;
        int[] skillList = AllParam.SECRETRAY_PATRONS_SKILL;// 羁绊技能
        for (int i=0; i<skillList.length; i++) {
            Skill skill = SkillManager.getSkill(skillList[i]);
            addPower += countPatronLevelUp(pbUserData, userInfo, userPower, userSecretary, skill, 1);
        }
        if (addPower > 0) {
            long newPower = userPower.getPower() + addPower;
            userPower.updatePower(pbUserData, userInfo, newPower);// 建筑收益放在addFavorite，创建经营技能时一起更新
        }

        userSecretary.addCharm(pbUserData, userInfo, secretaryMain.getCharmValue());
        //userSecretary.addFavorite(pbUserData, userInfo, userPower, userAffair, secretaryMain.getFavoriteValue());
        userSecretary.addFavorite(pbUserData, userInfo, userPower, userAffair, 30);
        userSecretary.doCreate();
        GameDataManager.unlockDecorateMain(pbUserData, userInfo, secretaryId);// 获得干员或是秘书时 自动解锁头像框
        if (pbUserData != null) {
            ProtoDataUtils.updatePBUserData(pbUserData, userSecretary);
        }

        long count = getSecretaryCount(userInfo.getId());
        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_124, count);
        RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_124, count);

        // 添加消耗获得日志
        List<Object> logParamsList = new ArrayList<>(Arrays.asList(logParams));
        logParamsList.add(secretaryMain.getQuality()); // 秘书需要记录品质
        Object[] newLogParamsList = logParamsList.toArray(new Object[0]);
        MotuLogManager.logItemIncome(userInfo, secretaryId, userSecretary.getId(), 0, 1, newLogParamsList);
        EventManager.updateKeyMan(userId, secretaryId);
        return userSecretary;
    }

    //  创建秘书经营技能数据
    public static void createSecrBusiness(PBUserData.Builder pbUserData, UserInfo userInfo, UserPower userPower, UserSecretary userSecretary) {
        long userId = userInfo.getId();
        int secrId = userSecretary.getSecretaryId();
        List<Integer> list = getPotenialSkillList();
        boolean isUpdate = false;
        for (int i=0; i<list.size(); i++) {
            int skillId = list.get(i);
            SecretaryPotentialSkill skill = getSecretaryPotentialSkill(skillId);
            if (skill.getNeedFavorite() <= userSecretary.getFavorite()) {// 亲密值达到的才解锁
                UserSecretaryBusiness userSecretaryBusiness = getUserSecretaryBusiness(userId, secrId, skill.getId());
                if (userSecretaryBusiness == null) {
                    userSecretaryBusiness = new UserSecretaryBusiness(userId, secrId, skill);
                    userSecretaryBusiness.addValue(pbUserData, userInfo, userPower, userSecretary, skill.getCharacterType(), skill.getMinValue());
                    userSecretaryBusiness.doCreate();//
                    ProtoDataUtils.updatePBUserData(pbUserData, userSecretaryBusiness, true);
                    isUpdate = true;// 有解锁新的经营技能
                } else {
                    break;// 已经解锁过了
                }
            }
        }

        if (isUpdate) {
            userPower.update();
            List<UserBuild> buildList = userPower.takeUserBuildList(0);
            BuildManager.batchUpdateBuildEarn(pbUserData, userInfo, userPower, buildList);// 更新这个性格的商业建筑的加成，并更新到userpower下发给客户端
        }
    }


    public static boolean checkRedPoint(UserInfo userInfo, CSGameSystemRedPointResponse.Builder red_build) {
        boolean hasRedPoint = false;
        List<UserSecretary> secretaryList = getUserSecretaries(userInfo.getId());
        RedPoint_Secretary.Builder secretaryRed = RedPoint_Secretary.newBuilder();
        for (UserSecretary userSecretary : secretaryList) {
            int secretaryId = userSecretary.getSecretaryId();
            SecretaryMain secretaryMain = getSecretaryMain(secretaryId);
            if (secretaryMain == null) {
                continue;
            }
            if (canIdentifyLevelUp(userSecretary, secretaryList.size())) {
                secretaryRed.addSecretaryIdentifyLevelUp(secretaryId);
                hasRedPoint = true;
            }
        }
        if (hasRedPoint) {
            red_build.setSecretary(secretaryRed);
        }
        return hasRedPoint;
    }

    public static boolean canIdentifyLevelUp(UserSecretary userSecretary, int secretaryCount) {
        int level = userSecretary.getIdentitySkillLevel();
        SecretaryIdentity nextLevel = SecretaryManager.getSecretaryIdentity(level + 1);
        if (nextLevel == null) { // 已达到最高等级
            return false;
        }
        SecretaryIdentity identity = SecretaryManager.getSecretaryIdentity(level);
        if (identity == null) { // 未配置当前等级
            return false;
        }
        // 未达到喜爱值或心情值
        if (userSecretary.getFavorite() < identity.getNeedFavorite() || userSecretary.getCharm() < identity.getNeedCharm()) {
            return false;
        }
        if (secretaryCount < identity.getNeedBeautyNum()) { // 秘书数量未达到
            return false;
        }
        return true;
    }

    /**
     * 秘书经营技能对建筑的收益的加成
     * @return jsonarray格式的字符串，固定6个值CHARACTER_TYPE_SIZE + 1，第一个表示所有性格，第二个表示性格1
     */
    public static String countEarnAddSecr(List<UserSecretary> secretaryList) {
        JsonArray jsonArray = SkillManager.createSkillEffectArray();
        int value0 = 0;
        int value1 = 0;
        int value2 = 0;
        int value3 = 0;
        int value4 = 0;
        int value5 = 0;
        for (UserSecretary userSecretary : secretaryList) {
            JsonArray tmp = userSecretary.getBusinessValueArray();
            if (tmp == null || tmp.size() == 0) {
                continue;
            }
            value0 += tmp.getInteger(0);
            value1 += tmp.getInteger(Constant.CHARACTER_TYPE_1);
            value2 += tmp.getInteger(Constant.CHARACTER_TYPE_2);
            value3 += tmp.getInteger(Constant.CHARACTER_TYPE_3);
            value4 += tmp.getInteger(Constant.CHARACTER_TYPE_4);
            value5 += tmp.getInteger(Constant.CHARACTER_TYPE_5);
        }
        jsonArray.set(0, value0);
        jsonArray.set(Constant.CHARACTER_TYPE_1, value1);
        jsonArray.set(Constant.CHARACTER_TYPE_2, value2);
        jsonArray.set(Constant.CHARACTER_TYPE_3, value3);
        jsonArray.set(Constant.CHARACTER_TYPE_4, value4);
        jsonArray.set(Constant.CHARACTER_TYPE_5, value5);

        return jsonArray.toString();
    }

    /**
     * 判断该秘书碎片的秘书是否已经获得了
     * @param userId
     * @param chipId
     * @return
     */
    public static boolean checkSecrByChipId(long userId, int chipId) {
        int secrId = BagManager.takePartnerSecrIdByChip(chipId);
        UserSecretary userSecretary = getUserSecretary(userId, secrId);
        if (userSecretary == null) {
            return false;// 未获得
        } else {
            return true;// 已经获得了
        }
    }

    /**
     * 计算升级秘书的羁绊技能增加的战力，只会增加羁绊干员的战力百分比或是固定值
     * @param pbUserData
     * @param userInfo
     * @param userPower
     */
    public static long countPatronLevelUp(PBUserData.Builder pbUserData, UserInfo userInfo, UserPower userPower, UserSecretary userSecretary, Skill skill, int newLevel) {
        if (skill == null) {
            return 0L;
        }
        JsonArray jsonArray = userSecretary.takePartnerIds();
        if (jsonArray == null || jsonArray.size() == 0) {
            return 0L;
        }

        long totalAdd = 0L;
        for (int i=0; i<jsonArray.size(); i++) {
            int partnerId = jsonArray.getInteger(i);
            UserPartner userPartner = PartnerManager.getUserPartner(userInfo.getId(), partnerId);
            if (userPartner == null) {
                continue;// 未解锁该干员
            }
            int addValue = skill.takeLevelUpDiff(newLevel);//  每升1级，增加的加成值
            if (skill.getEffectType() == SkillConstant.EFFECT_TYPE_31) {//羁绊技能，只有秘书才有 羁绊门客战力+定值
                userPartner.addSecrAdd(addValue);
            } else if (skill.getEffectType() == SkillConstant.EFFECT_TYPE_32) {// 羁绊技能，只有秘书才有 羁绊门客战力+%
                userPartner.addSecrAdd2(addValue);
            } else {
                continue;
            }
            userPartner.update();
            totalAdd += userPartner.reCountPower(userInfo, userPower);
            ProtoDataUtils.updatePBUserData(pbUserData, userPartner);
        }
        return totalAdd;
    }

    // userid 和secrId user_secrId
    public static String getBusinessUnique(long userId, int secrId) {
        return userId + "_" + secrId;
    }

    // 登录时异步重算秘书的经营技能
    public static void reCountBusiness(UserInfo userInfo) {
        UserPower userPower = GameUser.getUserPower(userInfo.getId());
        List<UserSecretary> list = getUserSecretaries(userInfo.getId());
        for (UserSecretary userSecretary : list) {
            userSecretary.reCountBusiness(userInfo, userPower);
            userSecretary.update();
        }
    }

    /**
     *  处理秘书基因技能升级
     * @param pbUserData
     * @param userInfo
     * @param userPower
     * @param userSecretary
     * @param skillId
     * @param newLevel 基因技能的等级，不是升级次数
     */
    public static void handleSecrIdentityLevelUp(PBUserData.Builder pbUserData,UserInfo userInfo, UserPower userPower, UserSecretary userSecretary, int skillId, int newLevel) {
        if (skillId == 0) {
            return;
        }
        Skill skill = SkillManager.getSkill(skillId);
        if (skill == null) {
            return;
        }
        int effectType = skill.getEffectType();
        int addValue = skill.takeLevelUpDiff(newLevel);//  每升1级，增加的加成值,增量更新，可能会委派多个干员，不能全量更新
        if (addValue == 0) {
            return;
        }

        boolean isUpdate = false;
        if (effectType == SkillConstant.EFFECT_TYPE_12) {// 提升武器等级上限 这个比较特殊记录在user_power,其他都在user_skill_effect
            userPower.addWeaponLevelMaxAdd(addValue);
            isUpdate = true;
        } else if (Tool.isInList(SkillConstant.SKILL_EFFECT_LIST, effectType)) {
            SkillManager.addSkillEffect(pbUserData, userInfo.getId(), skill, newLevel);
        }

        if (isUpdate) {
            userPower.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userPower);
        }
    }
}
